home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / gawk-2.11 / eval.c < prev    next >
Text File  |  1990-09-08  |  30KB  |  1,141 lines

  1. /*
  2.  * eval.c - gawk parse tree interpreter 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #include "awk.h"
  27. #include <math.h>
  28.  
  29. extern void do_print();
  30. extern void do_printf();
  31. extern NODE *do_match();
  32. extern NODE *do_sub();
  33. extern NODE *do_getline();
  34. extern NODE *concat_exp();
  35. extern int in_array();
  36. extern void do_delete();
  37. extern double pow();
  38.  
  39. static int eval_condition();
  40. static NODE *op_assign();
  41. static NODE *func_call();
  42. static NODE *match_op();
  43.  
  44. NODE *_t;        /* used as a temporary in macros */
  45. #ifdef MSDOS
  46. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  47. #endif
  48. NODE *ret_node;
  49.  
  50. /* More of that debugging stuff */
  51. #ifdef    DEBUG
  52. #define DBG_P(X) print_debug X
  53. #else
  54. #define DBG_P(X)
  55. #endif
  56.  
  57. /* Macros and variables to save and restore function and loop bindings */
  58. /*
  59.  * the val variable allows return/continue/break-out-of-context to be
  60.  * caught and diagnosed
  61.  */
  62. #define PUSH_BINDING(stack, x, val) (memcpy ((char *)(stack), (char *)(x), sizeof (jmp_buf)), val++)
  63. #define RESTORE_BINDING(stack, x, val) (memcpy ((char *)(x), (char *)(stack), sizeof (jmp_buf)), val--)
  64.  
  65. static jmp_buf loop_tag;    /* always the current binding */
  66. static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  67. static int func_tag_valid = 0;
  68. static jmp_buf func_tag;
  69. extern int exiting, exit_val;
  70.  
  71. /*
  72.  * This table is used by the regexp routines to do case independant
  73.  * matching. Basically, every ascii character maps to itself, except
  74.  * uppercase letters map to lower case ones. This table has 256
  75.  * entries, which may be overkill. Note also that if the system this
  76.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  77.  * defined to the linker, so gawk should not load.
  78.  *
  79.  * Do NOT make this array static, it is used in several spots, not
  80.  * just in this file.
  81.  */
  82. #if 'a' == 97    /* it's ascii */
  83. char casetable[] = {
  84.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  85.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  86.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  87.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  88.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  89.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  90.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  91.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  92.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  93.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  94.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  95.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  96.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  97.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  98.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  99.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  100.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  101.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  102.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  103.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  104.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  105.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  106.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  107.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  108.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  109.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  110.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  111.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  112.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  113.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  114.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  115.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  116.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  117.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  118.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  119.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  120.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  121.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  122.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  123.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  124.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  125.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  126.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  127.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  128. };
  129. #else
  130. #include "You lose. You will need a translation table for your character set."
  131. #endif
  132.  
  133. /*
  134.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  135.  * statement 
  136.  */
  137. int
  138. interpret(tree)
  139. NODE *tree;
  140. {
  141.     volatile jmp_buf loop_tag_stack; /* shallow binding stack for loop_tag */
  142.     static jmp_buf rule_tag;/* tag the rule currently being run, for NEXT
  143.                  * and EXIT statements.  It is static because
  144.                  * there are no nested rules */
  145.     register NODE *t = NULL;/* temporary */
  146.     volatile NODE **lhs;    /* lhs == Left Hand Side for assigns, etc */
  147.     volatile struct search *l;    /* For array_for */
  148.     volatile NODE *stable_tree;
  149.  
  150.     if (tree == NULL)
  151.         return 1;
  152.     sourceline = tree->source_line;
  153.     source = tree->source_file;
  154.     switch (tree->type) {
  155.     case Node_rule_list:
  156.         for (t = tree; t != NULL; t = t->rnode) {
  157.             tree = t->lnode;
  158.         /* FALL THROUGH */
  159.     case Node_rule_node:
  160.             sourceline = tree->source_line;
  161.             source = tree->source_file;
  162.             switch (setjmp(rule_tag)) {
  163.             case 0:    /* normal non-jump */
  164.                 /* test pattern, if any */
  165.                 if (tree->lnode == NULL 
  166.                     || eval_condition(tree->lnode)) {
  167.                     DBG_P(("Found a rule", (int)tree->rnode));
  168.                     if (tree->rnode == NULL) {
  169.                         /*
  170.                          * special case: pattern with
  171.                          * no action is equivalent to
  172.                          * an action of {print}
  173.                          */
  174.                         NODE printnode;
  175.  
  176.                         printnode.type = Node_K_print;
  177.                         printnode.lnode = NULL;
  178.                         printnode.rnode = NULL;
  179.                         do_print(&printnode);
  180.                     } else if (tree->rnode->type == Node_illegal) {
  181.                         /*
  182.                          * An empty statement
  183.                          * (``{ }'') is different
  184.                          * from a missing statement.
  185.                          * A missing statement is
  186.                          * equal to ``{ print }'' as
  187.                          * above, but an empty
  188.                          * statement is as in C, do
  189.                          * nothing.
  190.                          */
  191.                     } else
  192.                         (void) interpret(tree->rnode);
  193.                 }
  194.                 break;
  195.             case TAG_CONTINUE:    /* NEXT statement */
  196.                 return 1;
  197.             case TAG_BREAK:
  198.                 return 0;
  199.             default:
  200.                 cant_happen();
  201.             }
  202.             if (t == NULL)
  203.                 break;
  204.         }
  205.         break;
  206.  
  207.     case Node_statement_list:
  208.         for (t = tree; t != NULL; t = t->rnode) {
  209.             DBG_P(("Statements", (int)t->lnode));
  210.             (void) interpret(t->lnode);
  211.         }
  212.         break;
  213.  
  214.     case Node_K_if:
  215.         DBG_P(("IF", (int)tree->lnode));
  216.         if (eval_condition(tree->lnode)) {
  217.             DBG_P(("True", (int)tree->rnode->lnode));
  218.             (void) interpret(tree->rnode->lnode);
  219.         } else {
  220.             DBG_P(("False", (int)tree->rnode->rnode));
  221.             (void) interpret(tree->rnode->rnode);
  222.         }
  223.         break;
  224.  
  225.     case Node_K_while:
  226.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  227.  
  228.         DBG_P(("WHILE", (int)tree->lnode));
  229.         stable_tree = tree;
  230.         while (eval_condition(stable_tree->lnode)) {
  231.             switch (setjmp(loop_tag)) {
  232.             case 0:    /* normal non-jump */
  233.                 DBG_P(("DO", (int)stable_tree->rnode));
  234.                 (void) interpret(stable_tree->rnode);
  235.                 break;
  236.             case TAG_CONTINUE:    /* continue statement */
  237.                 break;
  238.             case TAG_BREAK:    /* break statement */
  239.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  240.                 return 1;
  241.             default:
  242.                 cant_happen();
  243.             }
  244.         }
  245.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  246.         break;
  247.  
  248.     case Node_K_do:
  249.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  250.         stable_tree = tree;
  251.         do {
  252.             switch (setjmp(loop_tag)) {
  253.             case 0:    /* normal non-jump */
  254.                 DBG_P(("DO", (int)stable_tree->rnode));
  255.                 (void) interpret(stable_tree->rnode);
  256.                 break;
  257.             case TAG_CONTINUE:    /* continue statement */
  258.                 break;
  259.             case TAG_BREAK:    /* break statement */
  260.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  261.                 return 1;
  262.             default:
  263.                 cant_happen();
  264.             }
  265.             DBG_P(("WHILE", (int)stable_tree->lnode));
  266.         } while (eval_condition(stable_tree->lnode));
  267.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  268.         break;
  269.  
  270.     case Node_K_for:
  271.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  272.         DBG_P(("FOR", (int)tree->forloop->init));
  273.         (void) interpret(tree->forloop->init);
  274.         DBG_P(("FOR.WHILE", (int)tree->forloop->cond));
  275.         stable_tree = tree;
  276.         while (eval_condition(stable_tree->forloop->cond)) {
  277.             switch (setjmp(loop_tag)) {
  278.             case 0:    /* normal non-jump */
  279.                 DBG_P(("FOR.DO", (int)stable_tree->lnode));
  280.                 (void) interpret(stable_tree->lnode);
  281.                 /* fall through */
  282.             case TAG_CONTINUE:    /* continue statement */
  283.                 DBG_P(("FOR.INCR", (int)stable_tree->forloop->incr));
  284.                 (void) interpret(stable_tree->forloop->incr);
  285.                 break;
  286.             case TAG_BREAK:    /* break statement */
  287.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  288.                 return 1;
  289.             default:
  290.                 cant_happen();
  291.             }
  292.         }
  293.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  294.         break;
  295.  
  296.     case Node_K_arrayfor:
  297. #define hakvar forloop->init
  298. #define arrvar forloop->incr
  299.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  300.         DBG_P(("AFOR.VAR", (int)tree->hakvar));
  301.         lhs = (volatile NODE **) get_lhs(tree->hakvar, 1);
  302.         t = tree->arrvar;
  303.         if (t->type == Node_param_list)
  304.             t = stack_ptr[t->param_cnt];
  305.         stable_tree = tree;
  306.         for (l = assoc_scan(t); l; l = assoc_next((struct search *)l)) {
  307.             deref = *((NODE **) lhs);
  308.             do_deref();
  309.             *lhs = dupnode(l->retval);
  310.             if (field_num == 0)
  311.                 set_record(fields_arr[0]->stptr,
  312.                     fields_arr[0]->stlen);
  313.             DBG_P(("AFOR.NEXTIS", (int)*lhs));
  314.             switch (setjmp(loop_tag)) {
  315.             case 0:
  316.                 DBG_P(("AFOR.DO", (int)stable_tree->lnode));
  317.                 (void) interpret(stable_tree->lnode);
  318.             case TAG_CONTINUE:
  319.                 break;
  320.  
  321.             case TAG_BREAK:
  322.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  323.                 field_num = -1;
  324.                 return 1;
  325.             default:
  326.                 cant_happen();
  327.             }
  328.         }
  329.         field_num = -1;
  330.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  331.         break;
  332.  
  333.     case Node_K_break:
  334.         DBG_P(("BREAK", (int)NULL));
  335.         if (loop_tag_valid == 0)
  336.             fatal("unexpected break");
  337.         longjmp(loop_tag, TAG_BREAK);
  338.         break;
  339.  
  340.     case Node_K_continue:
  341.         DBG_P(("CONTINUE", (int)NULL));
  342.         if (loop_tag_valid == 0)
  343.             fatal("unexpected continue");
  344.         longjmp(loop_tag, TAG_CONTINUE);
  345.         break;
  346.  
  347.     case Node_K_print:
  348.         DBG_P(("PRINT", (int)tree));
  349.         do_print(tree);
  350.         break;
  351.  
  352.     case Node_K_printf:
  353.         DBG_P(("PRINTF", (int)tree));
  354.         do_printf(tree);
  355.         break;
  356.  
  357.     case Node_K_next:
  358.         DBG_P(("NEXT", (int)NULL));
  359.         longjmp(rule_tag, TAG_CONTINUE);
  360.         break;
  361.  
  362.     case Node_K_exit:
  363.         /*
  364.          * In A,K,&W, p. 49, it says that an exit statement "...
  365.          * causes the program to behave as if the end of input had
  366.          * occurred; no more input is read, and the END actions, if
  367.          * any are executed." This implies that the rest of the rules
  368.          * are not done. So we immediately break out of the main loop.
  369.          */
  370.         DBG_P(("EXIT", (int)NULL));
  371.         exiting = 1;
  372.         if (tree) {
  373.             t = tree_eval(tree->lnode);
  374.             exit_val = (int) force_number(t);
  375.         }
  376.         free_temp(t);
  377.         longjmp(rule_tag, TAG_BREAK);
  378.         break;
  379.  
  380.     case Node_K_return:
  381.         DBG_P(("RETURN", (int)NULL));
  382.         t = tree_eval(tree->lnode);
  383.         ret_node = dupnode(t);
  384.         free_temp(t);
  385.         longjmp(func_tag, TAG_RETURN);
  386.         break;
  387.  
  388.     default:
  389.         /*
  390.          * Appears to be an expression statement.  Throw away the
  391.          * value. 
  392.          */
  393.         DBG_P(("E", (int)NULL));
  394.         t = tree_eval(tree);
  395.         free_temp(t);
  396.         break;
  397.     }
  398.     return 1;
  399. }
  400.  
  401. /* evaluate a subtree, allocating strings on a temporary stack. */
  402.  
  403. NODE *
  404. r_tree_eval(tree)
  405. NODE *tree;
  406. {
  407.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  408.     int i;
  409.     register NODE **lhs;
  410.     int di;
  411.     AWKNUM x, x2;
  412.     long lx;
  413.     extern NODE **fields_arr;
  414.  
  415.     source = tree->source_file;
  416.     sourceline = tree->source_line;
  417.     switch (tree->type) {
  418.     case Node_and:
  419.         DBG_P(("AND", (int)tree));
  420.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  421.                         && eval_condition(tree->rnode)));
  422.  
  423.     case Node_or:
  424.         DBG_P(("OR", (int)tree));
  425.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  426.                         || eval_condition(tree->rnode)));
  427.  
  428.     case Node_not:
  429.         DBG_P(("NOT", (int)tree));
  430.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  431.  
  432.         /* Builtins */
  433.     case Node_builtin:
  434.         DBG_P(("builtin", (int)tree));
  435.         return ((*tree->proc) (tree->subnode));
  436.  
  437.     case Node_K_getline:
  438.         DBG_P(("GETLINE", (int)tree));
  439.         return (do_getline(tree));
  440.  
  441.     case Node_in_array:
  442.         DBG_P(("IN_ARRAY", (int)tree));
  443.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  444.  
  445.     case Node_func_call:
  446.         DBG_P(("func_call", (int)tree));
  447.         return func_call(tree->rnode, tree->lnode);
  448.  
  449.     case Node_K_delete:
  450.         DBG_P(("DELETE", (int)tree));
  451.         do_delete(tree->lnode, tree->rnode);
  452.         return Nnull_string;
  453.  
  454.         /* unary operations */
  455.  
  456.     case Node_var:
  457.     case Node_var_array:
  458.     case Node_param_list:
  459.     case Node_subscript:
  460.     case Node_field_spec:
  461.         DBG_P(("var_type ref", (int)tree));
  462.         lhs = get_lhs(tree, 0);
  463.         field_num = -1;
  464.         deref = 0;
  465.         return *lhs;
  466.  
  467.     case Node_unary_minus:
  468.         DBG_P(("UMINUS", (int)tree));
  469.         t1 = tree_eval(tree->subnode);
  470.         x = -force_number(t1);
  471.         free_temp(t1);
  472.         return tmp_number(x);
  473.  
  474.     case Node_cond_exp:
  475.         DBG_P(("?:", (int)tree));
  476.         if (eval_condition(tree->lnode)) {
  477.             DBG_P(("True", (int)tree->rnode->lnode));
  478.             return tree_eval(tree->rnode->lnode);
  479.         }
  480.         DBG_P(("False", (int)tree->rnode->rnode));
  481.         return tree_eval(tree->rnode->rnode);
  482.  
  483.     case Node_match:
  484.     case Node_nomatch:
  485.     case Node_regex:
  486.         DBG_P(("[no]match_op", (int)tree));
  487.         return match_op(tree);
  488.  
  489.     case Node_func:
  490.         fatal("function `%s' called with space between name and (,\n%s",
  491.             tree->lnode->param,
  492.             "or used in other expression context");
  493.  
  494.     /* assignments */
  495.     case Node_assign:
  496.         DBG_P(("ASSIGN", (int)tree));
  497.         r = tree_eval(tree->rnode);
  498.         lhs = get_lhs(tree->lnode, 1);
  499.         *lhs = dupnode(r);
  500.         free_temp(r);
  501.         do_deref();
  502.         if (field_num == 0)
  503.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  504.         field_num = -1;
  505.         return *lhs;
  506.  
  507.     /* other assignment types are easier because they are numeric */
  508.     case Node_preincrement:
  509.     case Node_predecrement:
  510.     case Node_postincrement:
  511.     case Node_postdecrement:
  512.     case Node_assign_exp:
  513.     case Node_assign_times:
  514.     case Node_assign_quotient:
  515.     case Node_assign_mod:
  516.     case Node_assign_plus:
  517.     case Node_assign_minus:
  518.         return op_assign(tree);
  519.     default:
  520.         break;    /* handled below */
  521.     }
  522.  
  523.     /* evaluate subtrees in order to do binary operation, then keep going */
  524.     t1 = tree_eval(tree->lnode);
  525.     t2 = tree_eval(tree->rnode);
  526.  
  527.     switch (tree->type) {
  528.     case Node_concat:
  529.         DBG_P(("CONCAT", (int)tree));
  530.         t1 = force_string(t1);
  531.         t2 = force_string(t2);
  532.  
  533.         r = newnode(Node_val);
  534.         r->flags |= (STR|TEMP);
  535.         r->stlen = t1->stlen + t2->stlen;
  536.         r->stref = 1;
  537.         emalloc(r->stptr, char *, r->stlen + 1, "tree_eval");
  538.         memcpy(r->stptr, t1->stptr, t1->stlen);
  539.         memcpy(r->stptr + t1->stlen, t2->stptr, t2->stlen + 1);
  540.         free_temp(t1);
  541.         free_temp(t2);
  542.         return r;
  543.  
  544.     case Node_geq:
  545.     case Node_leq:
  546.     case Node_greater:
  547.     case Node_less:
  548.     case Node_notequal:
  549.     case Node_equal:
  550.         di = cmp_nodes(t1, t2);
  551.         free_temp(t1);
  552.         free_temp(t2);
  553.         switch (tree->type) {
  554.         case Node_equal:
  555.             DBG_P(("EQUAL", (int)tree));
  556.             return tmp_number((AWKNUM) (di == 0));
  557.         case Node_notequal:
  558.             DBG_P(("NOT_EQUAL", (int)tree));
  559.             return tmp_number((AWKNUM) (di != 0));
  560.         case Node_less:
  561.             DBG_P(("LESS_THAN", (int)tree));
  562.             return tmp_number((AWKNUM) (di < 0));
  563.         case Node_greater:
  564.             DBG_P(("GREATER_THAN", (int)tree));
  565.             return tmp_number((AWKNUM) (di > 0));
  566.         case Node_leq:
  567.             DBG_P(("LESS_THAN_EQUAL", (int)tree));
  568.             return tmp_number((AWKNUM) (di <= 0));
  569.         case Node_geq:
  570.             DBG_P(("GREATER_THAN_EQUAL", (int)tree));
  571.             return tmp_number((AWKNUM) (di >= 0));
  572.         default:
  573.             cant_happen();
  574.         }
  575.         break;
  576.     default:
  577.         break;    /* handled below */
  578.     }
  579.  
  580.     (void) force_number(t1);
  581.     (void) force_number(t2);
  582.  
  583.     switch (tree->type) {
  584.     case Node_exp:
  585.         DBG_P(("EXPONENT", (int)tree));
  586.         if ((lx = t2->numbr) == t2->numbr) {    /* integer exponent */
  587.             if (lx == 0)
  588.                 x = 1;
  589.             else if (lx == 1)
  590.                 x = t1->numbr;
  591.             else {
  592.                 /* doing it this way should be more precise */
  593.                 for (x = x2 = t1->numbr; --lx; )
  594.                     x *= x2;
  595.             }
  596.         } else
  597.             x = pow((double) t1->numbr, (double) t2->numbr);
  598.         free_temp(t1);
  599.         free_temp(t2);
  600.         return tmp_number(x);
  601.  
  602.     case Node_times:
  603.         DBG_P(("MULT", (int)tree));
  604.         x = t1->numbr * t2->numbr;
  605.         free_temp(t1);
  606.         free_temp(t2);
  607.         return tmp_number(x);
  608.  
  609.     case Node_quotient:
  610.         DBG_P(("DIVIDE", (int)tree));
  611.         x = t2->numbr;
  612.         free_temp(t2);
  613.         if (x == (AWKNUM) 0)
  614.             fatal("division by zero attempted");
  615.             /* NOTREACHED */
  616.         else {
  617.             x = t1->numbr / x;
  618.             free_temp(t1);
  619.             return tmp_number(x);
  620.         }
  621.  
  622.     case Node_mod:
  623.         DBG_P(("MODULUS", (int)tree));
  624.         x = t2->numbr;
  625.         free_temp(t2);
  626.         if (x == (AWKNUM) 0)
  627.             fatal("division by zero attempted in mod");
  628.             /* NOTREACHED */
  629.         lx = t1->numbr / x;    /* assignment to long truncates */
  630.         x2 = lx * x;
  631.         x = t1->numbr - x2;
  632.         free_temp(t1);
  633.         return tmp_number(x);
  634.  
  635.     case Node_plus:
  636.         DBG_P(("PLUS", (int)tree));
  637.         x = t1->numbr + t2->numbr;
  638.         free_temp(t1);
  639.         free_temp(t2);
  640.         return tmp_number(x);
  641.  
  642.     case Node_minus:
  643.         DBG_P(("MINUS", (int)tree));
  644.         x = t1->numbr - t2->numbr;
  645.         free_temp(t1);
  646.         free_temp(t2);
  647.         return tmp_number(x);
  648.  
  649.     default:
  650.         fatal("illegal type (%d) in tree_eval", tree->type);
  651.     }
  652.     return 0;
  653. }
  654.  
  655. /*
  656.  * This makes numeric operations slightly more efficient. Just change the
  657.  * value of a numeric node, if possible 
  658.  */
  659. void
  660. assign_number(ptr, value)
  661. NODE **ptr;
  662. AWKNUM value;
  663. {
  664.     extern NODE *deref;
  665.     register NODE *n = *ptr;
  666.  
  667. #ifdef DEBUG
  668.     if (n->type != Node_val)
  669.         cant_happen();
  670. #endif
  671.     if (n == Nnull_string) {
  672.         *ptr = make_number(value);
  673.         deref = 0;
  674.         return;
  675.     }
  676.     if (n->stref > 1) {
  677.         *ptr = make_number(value);
  678.         return;
  679.     }
  680.     if ((n->flags & STR) && (n->flags & (MALLOC|TEMP)))
  681.         free(n->stptr);
  682.     n->numbr = value;
  683.     n->flags |= (NUM|NUMERIC);
  684.     n->flags &= ~STR;
  685.     n->stref = 0;
  686.     deref = 0;
  687. }
  688.  
  689.  
  690. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  691. static int
  692. eval_condition(tree)
  693. NODE *tree;
  694. {
  695.     register NODE *t1;
  696.     int ret;
  697.  
  698.     if (tree == NULL)    /* Null trees are the easiest kinds */
  699.         return 1;
  700.     if (tree->type == Node_line_range) {
  701.         /*
  702.          * Node_line_range is kind of like Node_match, EXCEPT: the
  703.          * lnode field (more properly, the condpair field) is a node
  704.          * of a Node_cond_pair; whether we evaluate the lnode of that
  705.          * node or the rnode depends on the triggered word.  More
  706.          * precisely:  if we are not yet triggered, we tree_eval the
  707.          * lnode; if that returns true, we set the triggered word. 
  708.          * If we are triggered (not ELSE IF, note), we tree_eval the
  709.          * rnode, clear triggered if it succeeds, and perform our
  710.          * action (regardless of success or failure).  We want to be
  711.          * able to begin and end on a single input record, so this
  712.          * isn't an ELSE IF, as noted above.
  713.          */
  714.         if (!tree->triggered)
  715.             if (!eval_condition(tree->condpair->lnode))
  716.                 return 0;
  717.             else
  718.                 tree->triggered = 1;
  719.         /* Else we are triggered */
  720.         if (eval_condition(tree->condpair->rnode))
  721.             tree->triggered = 0;
  722.         return 1;
  723.     }
  724.  
  725.     /*
  726.      * Could just be J.random expression. in which case, null and 0 are
  727.      * false, anything else is true 
  728.      */
  729.  
  730.     t1 = tree_eval(tree);
  731.     if (t1->flags & NUMERIC)
  732.         ret = t1->numbr != 0.0;
  733.     else
  734.         ret = t1->stlen != 0;
  735.     free_temp(t1);
  736.     return ret;
  737. }
  738.  
  739. int
  740. cmp_nodes(t1, t2)
  741. NODE *t1, *t2;
  742. {
  743.     AWKNUM d;
  744.     AWKNUM d1;
  745.     AWKNUM d2;
  746.     int ret;
  747.     int len1, len2;
  748.  
  749.     if (t1 == t2)
  750.         return 0;
  751.     d1 = force_number(t1);
  752.     d2 = force_number(t2);
  753.     if ((t1->flags & NUMERIC) && (t2->flags & NUMERIC)) {
  754.         d = d1 - d2;
  755.         if (d == 0.0)    /* from profiling, this is most common */
  756.             return 0;
  757.         if (d > 0.0)
  758.             return 1;
  759.         return -1;
  760.     }
  761.     t1 = force_string(t1);
  762.     t2 = force_string(t2);
  763.     len1 = t1->stlen;
  764.     len2 = t2->stlen;
  765.     if (len1 == 0) {
  766.         if (len2 == 0)
  767.             return 0;
  768.         else
  769.             return -1;
  770.     } else if (len2 == 0)
  771.         return 1;
  772.     ret = memcmp(t1->stptr, t2->stptr, len1 <= len2 ? len1 : len2);
  773.     if (ret == 0 && len1 != len2)
  774.         return len1 < len2 ? -1: 1;
  775.     return ret;
  776. }
  777.  
  778. static NODE *
  779. op_assign(tree)
  780. NODE *tree;
  781. {
  782.     AWKNUM rval, lval;
  783.     NODE **lhs;
  784.     AWKNUM t1, t2;
  785.     long ltemp;
  786.     NODE *tmp;
  787.  
  788.     lhs = get_lhs(tree->lnode, 1);
  789.     lval = force_number(*lhs);
  790.  
  791.     switch(tree->type) {
  792.     case Node_preincrement:
  793.     case Node_predecrement:
  794.         DBG_P(("+-X", (int)tree));
  795.         assign_number(lhs,
  796.             lval + (tree->type == Node_preincrement ? 1.0 : -1.0));
  797.         do_deref();
  798.         if (field_num == 0)
  799.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  800.         field_num = -1;
  801.         return *lhs;
  802.  
  803.     case Node_postincrement:
  804.     case Node_postdecrement:
  805.         DBG_P(("X+-", (int)tree));
  806.         assign_number(lhs,
  807.             lval + (tree->type == Node_postincrement ? 1.0 : -1.0));
  808.         do_deref();
  809.         if (field_num == 0)
  810.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  811.         field_num = -1;
  812.         return tmp_number(lval);
  813.     default:
  814.         break;    /* handled below */
  815.     }
  816.  
  817.     tmp = tree_eval(tree->rnode);
  818.     rval = force_number(tmp);
  819.     free_temp(tmp);
  820.     switch(tree->type) {
  821.     case Node_assign_exp:
  822.         DBG_P(("ASSIGN_exp", (int)tree));
  823.         if ((ltemp = rval) == rval) {    /* integer exponent */
  824.             if (ltemp == 0)
  825.                 assign_number(lhs, (AWKNUM) 1);
  826.             else if (ltemp == 1)
  827.                 assign_number(lhs, lval);
  828.             else {
  829.                 /* doing it this way should be more precise */
  830.                 for (t1 = t2 = lval; --ltemp; )
  831.                     t1 *= t2;
  832.                 assign_number(lhs, t1);
  833.             }
  834.         } else
  835.             assign_number(lhs, (AWKNUM) pow((double) lval, (double) rval));
  836.         break;
  837.  
  838.     case Node_assign_times:
  839.         DBG_P(("ASSIGN_times", (int)tree));
  840.         assign_number(lhs, lval * rval);
  841.         break;
  842.  
  843.     case Node_assign_quotient:
  844.         DBG_P(("ASSIGN_quotient", (int)tree));
  845.         if (rval == (AWKNUM) 0)
  846.             fatal("division by zero attempted in /=");
  847.         assign_number(lhs, lval / rval);
  848.         break;
  849.  
  850.     case Node_assign_mod:
  851.         DBG_P(("ASSIGN_mod", (int)tree));
  852.         if (rval == (AWKNUM) 0)
  853.             fatal("division by zero attempted in %=");
  854.         ltemp = lval / rval;    /* assignment to long truncates */
  855.         t1 = ltemp * rval;
  856.         t2 = lval - t1;
  857.         assign_number(lhs, t2);
  858.         break;
  859.  
  860.     case Node_assign_plus:
  861.         DBG_P(("ASSIGN_plus", (int)tree));
  862.         assign_number(lhs, lval + rval);
  863.         break;
  864.  
  865.     case Node_assign_minus:
  866.         DBG_P(("ASSIGN_minus", (int)tree));
  867.         assign_number(lhs, lval - rval);
  868.         break;
  869.     default:
  870.         cant_happen();
  871.     }
  872.     do_deref();
  873.     if (field_num == 0)
  874.         set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  875.     field_num = -1;
  876.     return *lhs;
  877. }
  878.  
  879. NODE **stack_ptr;
  880.  
  881. static NODE *
  882. func_call(name, arg_list)
  883. NODE *name;        /* name is a Node_val giving function name */
  884. NODE *arg_list;        /* Node_expression_list of calling args. */
  885. {
  886.     register NODE *arg, *argp, *r;
  887.     NODE *n, *f;
  888.     volatile jmp_buf func_tag_stack;
  889.     volatile jmp_buf loop_tag_stack;
  890.     volatile int save_loop_tag_valid = 0;
  891.     volatile NODE **save_stack, *save_ret_node;
  892.     NODE **local_stack, **sp;
  893.     int count;
  894.     extern NODE *ret_node;
  895.  
  896.     /*
  897.      * retrieve function definition node
  898.      */
  899.     f = lookup(variables, name->stptr);
  900.     if (!f || f->type != Node_func)
  901.         fatal("function `%s' not defined", name->stptr);
  902. #ifdef FUNC_TRACE
  903.     fprintf(stderr, "function %s called\n", name->stptr);
  904. #endif
  905.     count = f->lnode->param_cnt;
  906.     emalloc(local_stack, NODE **, count * sizeof(NODE *), "func_call");
  907.     sp = local_stack;
  908.  
  909.     /*
  910.      * for each calling arg. add NODE * on stack
  911.      */
  912.     for (argp = arg_list; count && argp != NULL; argp = argp->rnode) {
  913.         arg = argp->lnode;
  914.         r = newnode(Node_var);
  915.         /*
  916.          * call by reference for arrays; see below also
  917.          */
  918.         if (arg->type == Node_param_list)
  919.             arg = stack_ptr[arg->param_cnt];
  920.         if (arg->type == Node_var_array)
  921.             *r = *arg;
  922.         else {
  923.             n = tree_eval(arg);
  924.             r->lnode = dupnode(n);
  925.             r->rnode = (NODE *) NULL;
  926.             free_temp(n);
  927.           }
  928.         *sp++ = r;
  929.         count--;
  930.     }
  931.     if (argp != NULL)    /* left over calling args. */
  932.         warning(
  933.             "function `%s' called with more arguments than declared",
  934.             name->stptr);
  935.     /*
  936.      * add remaining params. on stack with null value
  937.      */
  938.     while (count-- > 0) {
  939.         r = newnode(Node_var);
  940.         r->lnode = Nnull_string;
  941.         r->rnode = (NODE *) NULL;
  942.         *sp++ = r;
  943.     }
  944.  
  945.     /*
  946.      * Execute function body, saving context, as a return statement
  947.      * will longjmp back here.
  948.      *
  949.      * Have to save and restore the loop_tag stuff so that a return
  950.      * inside a loop in a function body doesn't scrog any loops going
  951.      * on in the main program.  We save the necessary info in variables
  952.      * local to this function so that function nesting works OK.
  953.      * We also only bother to save the loop stuff if we're in a loop
  954.      * when the function is called.
  955.      */
  956.     if (loop_tag_valid) {
  957.         int junk = 0;
  958.  
  959.         save_loop_tag_valid = (volatile int) loop_tag_valid;
  960.         PUSH_BINDING(loop_tag_stack, loop_tag, junk);
  961.         loop_tag_valid = 0;
  962.     }
  963.     save_stack = (volatile NODE **) stack_ptr;
  964.     stack_ptr = local_stack;
  965.     PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
  966.     save_ret_node = (volatile NODE *) ret_node;
  967.     ret_node = Nnull_string;    /* default return value */
  968.     if (setjmp(func_tag) == 0)
  969.         (void) interpret(f->rnode);
  970.  
  971.     r = ret_node;
  972.     ret_node = (NODE *) save_ret_node;
  973.     RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
  974.     stack_ptr = (NODE **) save_stack;
  975.  
  976.     /*
  977.      * here, we pop each parameter and check whether
  978.      * it was an array.  If so, and if the arg. passed in was
  979.      * a simple variable, then the value should be copied back.
  980.      * This achieves "call-by-reference" for arrays.
  981.      */
  982.     sp = local_stack;
  983.     count = f->lnode->param_cnt;
  984.     for (argp = arg_list; count > 0 && argp != NULL; argp = argp->rnode) {
  985.         arg = argp->lnode;
  986.         n = *sp++;
  987.         if (arg->type == Node_var && n->type == Node_var_array) {
  988.             arg->var_array = n->var_array;
  989.             arg->type = Node_var_array;
  990.         }
  991.         deref = n->lnode;
  992.         do_deref();
  993.         freenode(n);
  994.         count--;
  995.     }
  996.     while (count-- > 0) {
  997.         n = *sp++;
  998.         deref = n->lnode;
  999.         do_deref();
  1000.         freenode(n);
  1001.     }
  1002.     free((char *) local_stack);
  1003.  
  1004.     /* Restore the loop_tag stuff if necessary. */
  1005.     if (save_loop_tag_valid) {
  1006.         int junk = 0;
  1007.  
  1008.         loop_tag_valid = (int) save_loop_tag_valid;
  1009.         RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
  1010.     }
  1011.  
  1012.     if (!(r->flags & PERM))
  1013.         r->flags |= TEMP;
  1014.     return r;
  1015. }
  1016.  
  1017. /*
  1018.  * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
  1019.  * value of the var, or where to store the var's new value 
  1020.  */
  1021.  
  1022. NODE **
  1023. get_lhs(ptr, assign)
  1024. NODE *ptr;
  1025. int assign;        /* this is being called for the LHS of an assign. */
  1026. {
  1027.     register NODE **aptr;
  1028.     NODE *n;
  1029.  
  1030. #ifdef DEBUG
  1031.     if (ptr == NULL)
  1032.         cant_happen();
  1033. #endif
  1034.     deref = NULL;
  1035.     field_num = -1;
  1036.     switch (ptr->type) {
  1037.     case Node_var:
  1038.     case Node_var_array:
  1039.         if (ptr == NF_node && (int) NF_node->var_value->numbr == -1)
  1040.             (void) get_field(HUGE-1, assign); /* parse record */
  1041.         deref = ptr->var_value;
  1042. #ifdef DEBUG
  1043.         if (deref->type != Node_val)
  1044.             cant_happen();
  1045.         if (deref->flags == 0)
  1046.             cant_happen();
  1047. #endif
  1048.         return &(ptr->var_value);
  1049.  
  1050.     case Node_param_list:
  1051.         n = stack_ptr[ptr->param_cnt];
  1052.         deref = n->var_value;
  1053. #ifdef DEBUG
  1054.         if (deref->type != Node_val)
  1055.             cant_happen();
  1056.         if (deref->flags == 0)
  1057.             cant_happen();
  1058. #endif
  1059.         return &(n->var_value);
  1060.  
  1061.     case Node_field_spec:
  1062.         n = tree_eval(ptr->lnode);
  1063.         field_num = (int) force_number(n);
  1064.         free_temp(n);
  1065.         if (field_num < 0)
  1066.             fatal("attempt to access field %d", field_num);
  1067.         aptr = get_field(field_num, assign);
  1068.         deref = *aptr;
  1069.         return aptr;
  1070.  
  1071.     case Node_subscript:
  1072.         n = ptr->lnode;
  1073.         if (n->type == Node_param_list)
  1074.             n = stack_ptr[n->param_cnt];
  1075.         aptr = assoc_lookup(n, concat_exp(ptr->rnode));
  1076.         deref = *aptr;
  1077. #ifdef DEBUG
  1078.         if (deref->type != Node_val)
  1079.             cant_happen();
  1080.         if (deref->flags == 0)
  1081.             cant_happen();
  1082. #endif
  1083.         return aptr;
  1084.     case Node_func:
  1085.         fatal ("`%s' is a function, assignment is not allowed",
  1086.             ptr->lnode->param);
  1087.     default:
  1088.         cant_happen();
  1089.     }
  1090.     return 0;
  1091. }
  1092.  
  1093. static NODE *
  1094. match_op(tree)
  1095. NODE *tree;
  1096. {
  1097.     NODE *t1;
  1098.     struct re_pattern_buffer *rp;
  1099.     int i;
  1100.     int match = 1;
  1101.  
  1102.     if (tree->type == Node_nomatch)
  1103.         match = 0;
  1104.     if (tree->type == Node_regex)
  1105.         t1 = WHOLELINE;
  1106.     else {
  1107.         if (tree->lnode)
  1108.             t1 = force_string(tree_eval(tree->lnode));
  1109.         else
  1110.             t1 = WHOLELINE;
  1111.         tree = tree->rnode;
  1112.     }
  1113.     if (tree->type == Node_regex) {
  1114.         rp = tree->rereg;
  1115.         if (!strict && ((IGNORECASE_node->var_value->numbr != 0)
  1116.             ^ (tree->re_case != 0))) {
  1117.             /* recompile since case sensitivity differs */
  1118.             rp = tree->rereg =
  1119.                 mk_re_parse(tree->re_text,
  1120.                 (IGNORECASE_node->var_value->numbr != 0));
  1121.             tree->re_case =
  1122.                 (IGNORECASE_node->var_value->numbr != 0);
  1123.         }
  1124.     } else {
  1125.         rp = make_regexp(force_string(tree_eval(tree)),
  1126.             (IGNORECASE_node->var_value->numbr != 0));
  1127.         if (rp == NULL)
  1128.             cant_happen();
  1129.     }
  1130.     i = re_search(rp, t1->stptr, t1->stlen, 0, t1->stlen,
  1131.         (struct re_registers *) NULL);
  1132.     i = (i == -1) ^ (match == 1);
  1133.     free_temp(t1);
  1134.     if (tree->type != Node_regex) {
  1135.         free(rp->buffer);
  1136.         free(rp->fastmap);
  1137.         free((char *) rp);
  1138.     }
  1139.     return tmp_number((AWKNUM) i);
  1140. }
  1141.